//== SAGITTARIUS ============================================================================

//== FILEDOC =========================================================================

/** @file greylist_impl.h
  * @brief FIFO Queue-based implementation of the greylist
  * @details Uses segmented blocks to store the records. Primarily based on
  * Michaels' FIFO queue.
  */

//== BEGINNING OF CODE ===============================================================

#ifndef __SAGUTTARUIS__GREYLIST_IMPL__H_
#define __SAGUTTARUIS__GREYLIST_IMPL__H_

//== INCLUDES ========================================================================

#include "sagittarius/core/SagittariusCore.h"
#include "sagittarius/parallel/multisema.h"
#include <stddef.h>

#define GREYLIST_BLOCK_N (4096/sizeof(sg_glr))

#ifdef __cplusplus
extern "C" {
#endif

typedef struct __sg_glr {
    /// Next link in the list
    struct __sg_glr* nxt;
    
    /// Address of object
    void* v;
} sg_glr;

/** @brief Greylist segment
 */
typedef struct __greylist_seg {
    /// Address of block
    sg_glr* a;
    /// Length
    size_t l;
    /// Head
    sg_glr *hd;
    /// Tail
    sg_glr *tl;
    /// Next link in list
    struct __greylist_seg* nxt;
} greylist_seg;

/** @brief The greylist type
 * @details Implements a circular buffer. When the buffer becomes
 * full, it allocates a new buffer in memory and links the tail node
 * to it. When all items have been popped from a buffer, it is freed.
 */
typedef struct {
    uint32 n;
    
    /// Head
    greylist_seg *hd;
    /// Tail
    greylist_seg *tl;
    /// Sema
    //SG_DEF_MULTISEMA(sema);
} greylist_t;

#ifdef __cplusplus
}//extern "C"
#endif

#endif
